/**
 * 
 */
package edu.hitsz.cs.nlp.application;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Vector;

import edu.hitsz.cs.nlp.struct.ConllFile;

/**
 * @author tm
 *
 */
public class SequenceFileOperation {

	String splitSymbol="-";
	
	/**
	 * split sentences in input file into k files according to sentence
	 * @param inFileName
	 * @param kth
	 */
	public void split(String inFileName, int kth){
		ConllFile inFile=new ConllFile();
		inFile.readTrainFile(inFileName, 0);
		int totalNumber=inFile.sentenceNumber;
		for(int i=0;i<kth;i++){
			String trainName=inFileName+splitSymbol+"train"+splitSymbol+i;
			String testName=inFileName+splitSymbol+"test"+splitSymbol+i;
			ConllFile trainFile=new ConllFile();
			ConllFile testFile=new ConllFile();
			for(int j=0;j<totalNumber;j++){
				if(j>=(i*totalNumber/kth)&&j<((i+1)*totalNumber/kth))
					testFile.addSentence(inFile.totalSentence.get(j));
				else
					trainFile.addSentence(inFile.totalSentence.get(j));
			}
			testFile.storeFile(testName);
			trainFile.storeFile(trainName);
		}
	}
	
	/**
	 * split sentences in input file into k files according to random selection
	 * @param path
	 * @param inFileName
	 * @param kth
	 */
	public void splitRandom(String path, String inFileName, int kth){
		ConllFile inFile=new ConllFile();
		inFile.readTrainFile(inFileName, 0);
		int totalNumber=inFile.sentenceNumber;
		Vector<Integer> randomList=new Vector<Integer>();
		//generate random number in (0,kth)
		for(int i=0;i<totalNumber;i++){
			int randomNumber=(int)Math.floor(Math.random()*5);
			randomList.add(randomNumber);			
		}
		//
		for(int i=0;i<kth;i++){
			String trainName=inFileName+splitSymbol+"train"+splitSymbol+i;
			String testName=inFileName+splitSymbol+"test"+splitSymbol+i;
			ConllFile trainFile=new ConllFile();
			ConllFile testFile=new ConllFile();
			for(int j=0;j<totalNumber;j++){
				if(randomList.get(j)==i)
					testFile.addSentence(inFile.totalSentence.get(j));
				else
					trainFile.addSentence(inFile.totalSentence.get(j));
			}
			testFile.storeFile(testName);
			trainFile.storeFile(trainName);
		}
		//store random list file
		try{
			FileWriter listFile=new FileWriter(path+inFileName+"-list");
			for(Integer i : randomList){
				listFile.write(i+"\n");
			}
			listFile.close();
		}
		catch (IOException e){
			System.out.println("IOException: " + e);			
		}

	}
	
	/**
	 * combine sentences in many files into one file
	 * @param path
	 * @param outName 
	 * @param inName File name with number k, the format is "name-i"
	 * @param kth k files
	 */
	public void combine(String path, String outName, String inName, int kth){
		ConllFile outFile=new ConllFile();
		for(int i=0;i<kth;i++){
			String inFileName=inName+splitSymbol+i;
			ConllFile testFile=new ConllFile();
			testFile.readTrainFile(inFileName, 0);
			outFile.addFile(testFile);
		}
		outFile.storeFile(outName);		
	}
	
	/**
	 * combine sentences in many files into one file, the name of input and output file is same
	 * @param path
	 * @param fileName
	 * @param kth
	 */
	public void combine(String path, String fileName, int kth){
		combine(path,fileName,fileName,kth);
	}
	
	
	public void combineRandom(String path, String fileName, String listName, int kth){
		//read random list file
		Vector<Integer> randomList=new Vector<Integer>();
		File listFile=new File(path+listName);
		BufferedReader reader=null;		
		try{
			reader=new BufferedReader(new FileReader(listFile));
			String tmp=null;
			while((tmp=reader.readLine())!=null)
				randomList.add(Integer.parseInt(tmp.trim()));
			reader.close();
		}
		catch (IOException e){
			System.out.println("IOException: " + e);
			}
		int listNumber=randomList.size();
		//create seqlist to record the sequence of each sentence in each subfile at the entire file
		Vector<Integer> seqList=new Vector<Integer>();
		Vector<Integer> sigList=new Vector<Integer>();
		for(int i=0;i<kth;i++)
			sigList.add(-1);		
		for(int i=0;i<listNumber;i++){
			int j=randomList.get(i);
			int k=sigList.get(j)+1;
			sigList.set(j,k);
			seqList.add(k);
		}
		//
		ConllFile outFile=new ConllFile();
		outFile.addEmptySentences(listNumber);
		int testSig=0;
		for(int i=0;i<kth;i++){
			String inFileName=fileName+splitSymbol+i;
			ConllFile testFile=new ConllFile();
			testFile.readTrainFile(inFileName, 0);
			testSig+=testFile.sentenceNumber;
			for(int j=0;j<listNumber;j++){
				if(randomList.get(j)==i){
					outFile.totalSentence.set(j, testFile.totalSentence.get(seqList.get(j)));
				}
			}
		}
		if(testSig!=listNumber){
			System.out.println("The number in list and separate file don't matter. Please check");
		}
		outFile.storeFile(fileName);			
	}
	
	
	/**
	 * Store sentences in reverse order. It operates like first storing the nth sentence, then n-1th, ... , final the first one.
	 * @param outPath
	 * @param fileName
	 */
	public void storeReverseFile(String path,String inName, String outName)
	{
		ConllFile inFile=new ConllFile();
		inFile.readTrainFile(inName, 0);
		String outFileName=path+outName;
		try{
			FileWriter outFileWriter=new FileWriter(outFileName);
			for(int i=inFile.sentenceNumber-1;i>=inFile.sentenceNumber;i--){	
				inFile.totalSentence.get(i).storeSentence(outFileWriter);
			}
			outFileWriter.close();
			System.out.println("\nStore train file has done!");
		}
		catch (IOException e){
			System.out.println("IOException: " + e);
		}
	}
	

	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SequenceFileOperation newOpe=new SequenceFileOperation();
		newOpe.splitRandom("/windows/F/experiments/crf/", "20wpc-fea", 5);
		//newOpe.combineRandom("/windows/F/experiments/crf/","20wp-test","20wp-list",5);

	}

}
